package com.happy_lab_management.demo.admin.experimentApplication.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.happy_lab_management.context.BaseContext;
import com.happy_lab_management.demo.admin.experimentApplication.service.ExperimentApplicationService;
import com.happy_lab_management.demo.admin.labSchedule.service.LabScheduleService;
import com.happy_lab_management.demo.admin.semester.service.SemesterService;
import com.happy_lab_management.demo.admin.user.service.TeacherService;
import com.happy_lab_management.demo.common.labType.service.LabTypeService;
import com.happy_lab_management.demo.common.section.service.SectionService;
import com.happy_lab_management.demo.common.weekday.service.WeekdayService;
import com.happy_lab_management.demo.technician.lab.service.LabService;
import com.happy_lab_management.entity.*;
import com.happy_lab_management.entity.DTO.ExperimentApplicationCheckDTO;
import com.happy_lab_management.entity.DTO.ExperimentApplicationDTO;
import com.happy_lab_management.entity.DTO.ScheduleDTO;
import com.happy_lab_management.entity.VO.EquipmentRepairVO;
import com.happy_lab_management.entity.VO.ExperimentApplicationVO;
import com.happy_lab_management.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static javax.management.Query.or;

@RequestMapping("/admin/experimentApplication")
@RestController("adminExp")
@Slf4j
public class ExperimentApplicationController {
    @Autowired
    private ExperimentApplicationService experimentApplicationService;
    @Autowired
    private LabScheduleService labScheduleService;
    @Autowired
    private LabService labService;
    @Autowired
    private TeacherService teacherService;
    @Autowired
    private SemesterService semesterService;
    @Autowired
    private WeekdayService weekdayService;
    @Autowired
    private SectionService sectionService;
    @Autowired
    private LabTypeService labTypeService;

    /**
     * 分页查询
     *
     * @return
     */
    @RequestMapping("/list")
    public Result<IPage<ExperimentApplicationVO>> list(@RequestParam(required = false)  String teacherName,
                                                       @RequestParam(required = false)  String    status,
                                                 @RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
                                                 @RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize
    ) {
        QueryWrapper<ExperimentApplication> queryWrapper = new QueryWrapper<>();
        //条件
        //教师
        if (teacherName != null && !teacherName.isEmpty()) {
            List<Integer> teacherIds = teacherService.list(new QueryWrapper<Teacher>().like("name", teacherName))
                    .stream().map(Teacher::getId).collect(Collectors.toList());
            queryWrapper.in("teacher_id", teacherIds);
        }
        //申请状态
        if (status != null && !status.isEmpty()) {
            queryWrapper.eq("status", status);
        }
        //查到整个labType=》labTypeName
        List<LabType> labTypes = labTypeService.list();
        Map<Integer, String> labTypeMap = labTypes.stream()
                .collect(Collectors.toMap(
                        LabType::getId, // key 为 LabType 的 id
                        LabType::getLabTypeName // value 为 LabType 的 labTypeName
                ));

        Page<ExperimentApplication> page = new Page<>(pageNo, pageSize);
        IPage<ExperimentApplication> pageList = experimentApplicationService.page(page, queryWrapper);

        List<ExperimentApplicationVO> vos = pageList.getRecords().stream().map(er -> {
            ExperimentApplicationVO vo = new ExperimentApplicationVO();
            vo.setId(er.getId());
            vo.setTeacherName(teacherService.getById( er.getTeacherId()).getName());
            vo.setSemesterName(semesterService.getById(er.getSemesterId()).getSemesterName());
            vo.setCourseName(er.getCourseName());
            vo.setLabType(er.getLabType());
            vo.setLabTypeName(labTypeMap.get(Integer.parseInt(er.getLabType())));
            vo.setClassname(er.getClassname());
            vo.setStudentCount(er.getStudentCount());
            vo.setStartWeek(er.getStartWeek());
            vo.setEndWeek(er.getEndWeek());
            vo.setWeekdayName(weekdayService.getById(er.getWeekday()).getWeekdayName());
            vo.setSectionName(sectionService.getById(er.getSection()).getSectionName());
            vo.setStatus(er.getStatus());

            return vo;
        }).collect(Collectors.toList());
        Page<ExperimentApplicationVO> voPage = new Page<>();
        voPage.setRecords(vos);
        voPage.setTotal(pageList.getTotal());
        voPage.setSize(pageList.getSize());
        voPage.setCurrent(pageList.getCurrent());
        return Result.success(voPage);
    }

    /**
     * 根据教师填写的实验课申请登记，查询可用的实验室
     *
     * @param
     * @return
     */
    @RequestMapping("/selectLabs")
    public Result<List<Lab>> schedule(@RequestParam Integer id){
        if(id==null){
            return Result.error("请传递参数");
        }
        ExperimentApplication experimentApplication = experimentApplicationService.getById(id);
        if(experimentApplication==null){
            return Result.error("找不到该申请");
        }
        /*根据“实验课申请登记”的“实验室类型”确定可以选择的实验室范围*/
        /*根据“实验课申请登记”的“学生人数”和实验室设备数决定分配哪几间实验室*/
        /*根据“实验课申请登记”的“起始周”、“结束周”和已经排课的情 况避免实验室冲突*/
        if("已排课".equals(experimentApplication.getStatus())){
            return Result.error("该申请已完成排课");
        }

        QueryWrapper<Lab> labQueryWrapper=new QueryWrapper<>();
        labQueryWrapper.eq("lab_type",experimentApplication.getLabType());

        Integer studentCount = experimentApplication.getStudentCount();
        labQueryWrapper.gt("equipment_count",studentCount);
        //可使用的实验室
        List<Lab> availableLabs = labService.list(labQueryWrapper);

        //时间有冲突的实验室
        QueryWrapper<LabSchedule> scheduleQueryWrapper=new QueryWrapper<>();
        //学期
        scheduleQueryWrapper.eq("semester_id",experimentApplication.getSemesterId());
        //周次
        // 时间冲突的查询
        scheduleQueryWrapper.and(wrapper ->
                wrapper.gt("end_week", experimentApplication.getStartWeek())
                        .and(innerWrapper -> innerWrapper.lt("start_week", experimentApplication.getEndWeek()))
        );


        //周（几）
        scheduleQueryWrapper.eq("weekday",experimentApplication.getWeekday());


        scheduleQueryWrapper.eq("section",experimentApplication.getSection());
        //找出时间冲突的实验室
        List<LabSchedule> conflictSchedules = labScheduleService.list(scheduleQueryWrapper);
        if (conflictSchedules.isEmpty()){
            return Result.success(availableLabs);
        }

        List<Lab> conflictScheduleLab=new ArrayList<>();
        List<Integer> labIds = conflictSchedules.stream()
                .map(LabSchedule::getLabId)
                .collect(Collectors.toList());
        labIds.forEach(labId->{
            Lab lab = labService.getById(labId);
            conflictScheduleLab.add(lab);
        });
        availableLabs.removeIf(lab -> conflictScheduleLab.contains(lab));

        return Result.success(availableLabs);
    }

    /**
     * 通过selectFreeLabs接口，超级管理员寻找排课实验室
     * 根据“实验课申请登记”的“起始周”、“结束周”和已经排课的情况避免实验室冲突
     * 插入实验排课表
     * @param
     * @return
     */
    @RequestMapping("/addSchedule")
    @Transactional
    public Result<String> scheduleExperiment(@RequestBody ScheduleDTO scheduleDTO){
        //查出申请表单
        Integer experimentApplicationId = scheduleDTO.getExperimentApplicationId();
        Integer labId=scheduleDTO.getLabId();
        ExperimentApplication experimentApplication=experimentApplicationService.getById(experimentApplicationId);
        //查询是否冲突

        //插入数据
        LabSchedule labSchedule =new LabSchedule();
        labSchedule.setSemesterId(experimentApplication.getSemesterId());
        labSchedule.setLabId(labId);
        labSchedule.setStartWeek(experimentApplication.getStartWeek());
        labSchedule.setEndWeek(experimentApplication.getEndWeek());
        labSchedule.setWeekday(experimentApplication.getWeekday());
        labSchedule.setSection(experimentApplication.getSection());
        labSchedule.setCourseName(experimentApplication.getCourseName());

        labSchedule.setTeacherName(experimentApplication.getTeacherId().toString());
        labSchedule.setClassname(experimentApplication.getClassname());

        labScheduleService.save(labSchedule);
        experimentApplication.setStatus("已排课");
        experimentApplicationService.updateById(experimentApplication);
        return Result.success("排课成功");

    }



    /**
     * 查询未排课的申请
     * @return
     */
    @RequestMapping("/listApplication")
    public Result<List<ExperimentApplication>> ListUnScheduled(){
        List<ExperimentApplication> experimentApplications= experimentApplicationService.ListUnScheduled();
        return Result.success(experimentApplications);
    }

    /**
     * 查询所有实验室类型
     * @return
     */
    @RequestMapping("/listType")
    public Result<List<String>> listAlLType(){
        return labService.listAlLType();
    }

    @RequestMapping("/reject")
    public Result<String> reject(@RequestParam Integer id) {
        ExperimentApplication experimentApplication = experimentApplicationService.getById(id);
        if (experimentApplication != null) {
            experimentApplication.setStatus("驳回");
            experimentApplicationService.updateById(experimentApplication);
            return Result.success("驳回成功");
        } else {
            return Result.error("找不到对应的申请");
        }
    }



}
